package com.ai.networking.netty.client;

import com.ai.common.constant.PlcConstants;
import com.ai.entity.comm.SysNetty;
import com.ai.entity.network.IdentifySysToL1Message;
import com.ai.networking.netty.comm.CommonNetty;
import com.ai.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 新链路 plc4 发送心跳及报文
 * @Author jiaok
 * @Date 2023-08-02 10:40
 */
@Slf4j
@Component
@Configuration
@EnableScheduling
public class BootNettyNewLink {

    private static final Integer MESSAGE_LEN=46;
    public static volatile AtomicInteger heartCount=new AtomicInteger(0);

    /**
     * 1运行中（开始）、0未运行（停止）
     */
    public static volatile AtomicInteger runStatus=new AtomicInteger(0);
    /**
     * 由算法传递该参数
     */
    public static volatile AtomicInteger spacing= new AtomicInteger(0);
    //0未重叠、1重叠、2 距离过近
    public static volatile AtomicInteger overlapStatus= new AtomicInteger(0);

    // TODO: 2023-11-16
    /**
     * 时间取项目启动时间前一小时的毫秒值
     */
    public static volatile Long timeMillisFlag = System.currentTimeMillis()-(60*60*1000);

    public static void main(String[] args) {
        long currentTimeMillis = System.currentTimeMillis();
        System.out.println("当前时间的毫秒值： " + currentTimeMillis);
    }

    /**
     * 使用定时器发送心跳
     */
    // TODO: 2023-12-08 心跳暂时停止发送
//    @Scheduled(cron = "0/1 * * * * ?")
    public void heart_timer() {
        // 心跳自定义

        // 所有已经连接的客户端
        if (CommonNetty.NATIVE_CLIENT_MAP.size() > 0) {
            //所有需要并且已经连接的客户端
            for (Map.Entry<String, SysNetty> entry : CommonNetty.NATIVE_CLIENT_MAP.entrySet()) {
                String code = entry.getKey();
               if (code.equals(PlcConstants.PLC_4_CODE)){
                   SysNetty sysNetty = entry.getValue();
                   // 判断是否创建成功   ----------   通过code来判断对应的功能是哪个
                   if (BootNettyClientChannelCache.channelMapCache.containsKey(code)) {
                       // 创建成功
                       BootNettyClientChannel bootNettyChannel = BootNettyClientChannelCache.channelMapCache.get(code);
                       if (bootNettyChannel != null && bootNettyChannel.getChannel().isOpen()) {
                           // : 2023-06-20 修改心跳信号内容----不同的端口 发送的心跳内容不同
                           IdentifySysToL1Message identifySysToL1Message1 = new IdentifySysToL1Message();
                           //报文长度默认为46
                           identifySysToL1Message1.setTelLen(MESSAGE_LEN);
                           //运行状态
                           identifySysToL1Message1.setRunStatus(runStatus);
                           //间距
                           identifySysToL1Message1.setSpacing(String.valueOf(spacing));
                           //重叠状态
                           identifySysToL1Message1.setOverlapStatus(String.valueOf(overlapStatus));

                           byte[] message = createMessageToPlc4(identifySysToL1Message1);

                               log.info("=========================== plc4链路 向发送 {} 心跳  ===========================",code);
                               log.info("=========================== 心跳内容:{}  ===========================",message);

                            bootNettyChannel.getChannel().writeAndFlush(Unpooled.copiedBuffer(message));
                       }
                   } else {
                       log.info(code + "创建失败,准备重连...");
                       new BootNettyClientThread(sysNetty).start();
                   }
               }
            }
        }
    }

    /**
     * 创建发送给plc4的字节报文数组
     * @param identifySysToL1Message
     * @return
     */
    private static byte[] createMessageToPlc4(IdentifySysToL1Message identifySysToL1Message) {
        byte[] messageBytes = new byte[MESSAGE_LEN];

        // 消息長度 2
        StringUtil.byteInsert(messageBytes, StringUtil.intToByteArray(MESSAGE_LEN,2),0);
        // 算法运行状态 1位
        StringUtil.byteInsert(messageBytes,StringUtil.intToByteArray(Integer.parseInt(String.valueOf(identifySysToL1Message.getRunStatus())),1),2);
        // 两块板胚之间的距离 2位
        StringUtil.byteInsert(messageBytes,StringUtil.intToByteArray(Integer.parseInt(identifySysToL1Message.getSpacing()),2),3);
        //重叠状态 1位
        StringUtil.byteInsert(messageBytes,StringUtil.intToByteArray(Integer.parseInt(identifySysToL1Message.getOverlapStatus()),1),5);
        //預留字段 38位
        String spare= (StringUtils.isBlank(identifySysToL1Message.getSpare())?"":identifySysToL1Message.getSpare());
        StringUtil.byteInsert(messageBytes,StringUtil.convertStringToHex(spare),6);
        if (heartCount.get()==999){
            heartCount.set(0);
        }
        StringUtil.byteInsert(messageBytes, StringUtil.intToByteArray(heartCount.incrementAndGet(),2),44);

        return messageBytes;
    }
}
